10. Pandas-Series和DataFrame创建

本章概要

  • 学习材料:带索引的 Series、二维数组和字段字典。
  • 本章任务:运行 lst-df-from-numpylst-series-align,创建 DataFrame 并观察标签对齐。
  • 完成后你将得到:行列标签、shape 与标签对齐后缺失位置。
  • 自我检查:检查索引唯一、列数与数组宽度一致;重复索引或意外 NaN 时先检查原因。
  • 拓展练习:把创建步骤应用到长三角公司季度表。

核心与后续预览

  • 本章核心:创建 Series/DataFrame、绑定标签、查看 shape、用 loc/iloc 访问,以及观察 Series 标签自动对齐。
  • 扩展预览:筛选、转置、描述统计与缺失值处理只作后续章节导航,不纳入本章随堂练习。
  • 遇到问题时:主要创建步骤出现重复索引、列宽错位或意外缺失时,先诊断标签与输入形状,不用填充掩盖问题。

Pandas:Python数据分析的基石

Pandas建立在NumPy之上,提供了专为结构化数据处理设计的高级工具。

  • DataFrame:二维表格数据结构(类似Excel表格)
  • Series:一维带标签数组(类似DataFrame的单列)
  • Index:行标签,支持时间序列索引
  • 向量化操作:类似NumPy的高性能运算

Pandas为什么优于Excel?

对比维度 Pandas Excel
数据量 受内存与计算资源约束;可超过单工作表上限,但须按负载验证 单工作表最多 1,048,576 行
可重复性 代码可重现 操作难以追踪
自动化 可构建处理流程 需手动操作
复杂计算 分组、聚合、变换 功能有限
时间序列 专门优化 基础支持

选择边界:两者的可用规模都取决于任务、硬件和实现;先用代表性数据做内存与运行时间基准。

导入Pandas库

Listing 1: 导入Pandas库
展开Pandas导入与版本检查代码
# 导入Pandas库,使用pd作为别名(行业惯例)
import pandas as pd
# 导入NumPy库,Pandas依赖NumPy进行数值计算
import numpy as np

# 查看Pandas版本
print(f'Pandas版本: {pd.__version__}')

# 测试Pandas是否正常工作
test_data = pd.Series([1, 2, 3, 4, 5])
print(f'\n测试数据:\n{test_data}')
Pandas版本: 2.3.3

测试数据:
0    1
1    2
2    3
3    4
4    5
dtype: int64

Series:一维带标签数组

Series是Pandas的一维数据结构,类似NumPy数组但带标签索引

语法pd.Series(data, index=index, dtype=dtype, name=name)

  • Values:底层数据(NumPy数组)
  • Index:行标签(字符串、数字、日期等)
  • Name:Series的名称(可选)
  • dtype:数据类型

运行前预测|任务一:创建股票涨跌幅Series

  • 输入预测:运行前先写出 list_maynames 的业务含义、数据类型或取值范围,并判断哪一个输入最可能改变结果。
  • 结果预测:不展开答案,先预测将得到s 的结果;同时写出方向、数量级或表格/图形结构。
  • 完成要求:能独立说明本任务从输入到“任务一:创建股票涨跌幅Series”结果的关键步骤,原样录入平台代码并得到可核对的运行结果。

⭐ 任务一:创建股票涨跌幅Series

# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
#任务一:创建股票涨跌幅Series
import pandas as pd
list_may=[-0.0035,-0.0338,0.0058,-0.0298]  # 定义列表list_may
name=['中国卫星','中国软件','中国银行','上汽集团']  # 定义列表name
s=pd.Series(list_may,index=name)  # 创建Series序列s
print(s)  # 输出任务一:创建股票涨跌幅Series

任务复盘|任务一:创建股票涨跌幅Series

运行后核对:核对 list_maynames 是否按预测参与运算,实际输出是否与预测一致;若不一致,先检查类型、单位、索引/字段和运算顺序。

拓展练习:把输入表替换为本地中国上市公司数据的同结构子集;指出必须保持的字段、数据类型和质量检查。

任务一代码解析

解析层 关键点 检查
输入 list_may 是涨跌幅;name 是股票标签 两者长度一致
构造 pd.Series(data, index=...) 建立一维带标签数组 左侧索引、右侧数值
用途 标签查找、自动对齐、日期索引 不把位置当标签

Series的索引访问

Listing 2: Series的索引访问方式
展开Series索引访问代码
s = pd.Series(
    [-0.0035, -0.0338, 0.0058, -0.0298],
    index=['中国卫星', '中国软件', '中国银行', '上汽集团'],
    name='涨跌幅'
)

# 通过显式标签索引访问
print(f'中国软件涨跌幅: {s.loc["中国软件"]:.4f}')

# 通过显式位置索引访问,避免整数键语义歧义
print(f'第一个元素: {s.iloc[0]:.4f}')

# 通过显式位置切片访问前两个元素
print(f'前两个元素:\n{s.iloc[:2]}')
中国软件涨跌幅: -0.0338
第一个元素: -0.0035
前两个元素:
中国卫星   -0.0035
中国软件   -0.0338
Name: 涨跌幅, dtype: float64

预览|Series 条件筛选与统计(第11/13章)

Listing 3: Series的条件筛选与统计摘要
展开Series条件筛选与统计代码
s = pd.Series(
    [-0.0035, -0.0338, 0.0058, -0.0298],
    index=['中国卫星', '中国软件', '中国银行', '上汽集团'],
    name='涨跌幅'
)

# 布尔索引:筛选负收益股票
print('负收益股票:')
print(s[s < 0])

# 统计摘要
print(f'\n统计摘要:')
print(s.describe())
负收益股票:
中国卫星   -0.0035
中国软件   -0.0338
上汽集团   -0.0298
Name: 涨跌幅, dtype: float64

统计摘要:
count    4.000000
mean    -0.015325
std      0.019467
min     -0.033800
25%     -0.030800
50%     -0.016650
75%     -0.001175
max      0.005800
Name: 涨跌幅, dtype: float64

预览|Series 运算与排序(第11章)

Listing 4: Series的向量化运算与排序
展开Series运算与排序代码
s = pd.Series(
    [-0.0035, -0.0338, 0.0058, -0.0298],
    index=['中国卫星', '中国软件', '中国银行', '上汽集团'],
    name='涨跌幅'
)

# 向量化运算:涨跌幅翻倍
print('涨跌幅翻倍:')
print(s * 2)

# 按值升序排序
print('\n按值排序(升序):')
print(s.sort_values())

# 按值降序排序
print('\n按值排序(降序):')
print(s.sort_values(ascending=False))
涨跌幅翻倍:
中国卫星   -0.0070
中国软件   -0.0676
中国银行    0.0116
上汽集团   -0.0596
Name: 涨跌幅, dtype: float64

按值排序(升序):
中国软件   -0.0338
上汽集团   -0.0298
中国卫星   -0.0035
中国银行    0.0058
Name: 涨跌幅, dtype: float64

按值排序(降序):
中国银行    0.0058
中国卫星   -0.0035
上汽集团   -0.0298
中国软件   -0.0338
Name: 涨跌幅, dtype: float64

索引 vs 位置:关键区别

访问方式 语法 说明 示例
标签索引 s.loc['label'] 使用索引名 s.loc['中国卫星']
位置索引 s.iloc[0] 使用整数位置 s.iloc[0]
标签切片 s.loc['a':'c'] 包含两端 s.loc['A':'C']
位置切片 s.iloc[0:2] 不包含末端 s.iloc[0:2]

易混淆点:标签切片包含末端,位置切片不包含;不要用 s[0] 猜测“整数标签还是位置”,Pandas 2.3 已提示此位置语义将改变。

DataFrame:二维表格数据

DataFrame是Pandas的二维数据结构,类似Excel表格SQL表

语法pd.DataFrame(data, index=index, columns=columns)

  • Index:行标签(日期、ID等)
  • Columns:列名(变量名)
  • Values:二维NumPy数组

运行前预测|任务二:创建股票涨跌幅DataFrame

  • 输入预测:运行前先写出 dataindexdf 的业务含义、数据类型或取值范围,并判断哪一个输入最可能改变结果。
  • 结果预测:不展开答案,先预测将得到df 的结果;同时写出方向、数量级或表格/图形结构。
  • 完成要求:能独立说明本任务从输入到“任务二:创建股票涨跌幅DataFrame”结果的关键步骤,原样录入平台代码并得到可核对的运行结果。

⭐ 任务二:创建股票涨跌幅DataFrame

展开完整代码(投影默认折叠)
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
#任务二:创建股票涨跌幅DataFrame
import pandas as pd
data={  # 定义data字典,开始构建键值映射
    '中国卫星':[-0.0351,0.0172,-0.0035,-0.0246,0.0394],  # "中国卫星"的数据序列
    '中国软件':[-0.0139,0.0243,-0.0338,0.0146,0.0001],  # "中国软件"的数据序列
    '中国银行':[-0.0139,0.0243,-0.0338,0.0146,0.0001],  # "中国银行"的数据序列
    '上汽集团':[0.0212,0.0021,-0.0298,-0.0027,-0.0143]  # "上汽集团"的数据序列
}  # 数据结构定义结束
index=['20200525','20200526','20200527','20200528','20200529']  # 定义列表index
df=pd.DataFrame(data,index)  # 创建数据框df
print(df)  # 输出数据框数据

任务复盘|任务二:创建股票涨跌幅DataFrame

运行后核对:核对 dataindexdf 是否按预测参与运算,实际输出是否与预测一致;若不一致,先检查类型、单位、索引/字段和运算顺序。

拓展练习:把输入表替换为本地中国上市公司数据的同结构子集;指出必须保持的字段、数据类型和质量检查。

任务二代码解析

解析层 关键点 检查
输入 data 的键成为列名;各列表长度一致 行列维度可核对
构造 pd.DataFrame(data, index) 用交易日期作行标签 索引无重复
索引选择 时间分析用 DatetimeIndex;无业务标签才用 RangeIndex 类型与排序正确

创建DataFrame:从列表的列表

Listing 5: 从列表的列表创建DataFrame
展开从列表的列表创建DataFrame代码
# 列表的列表,每个子列表代表一行数据
data_list = [
    ['中信证券', 24.78, 0.05],
    ['国泰君安', 20.15, -0.02],
    ['海通证券', 14.03, 0.03]
]
# 创建DataFrame并指定列名
df1 = pd.DataFrame(data_list, columns=['名称', '价格', '涨跌幅'])
print(df1)
     名称     价格   涨跌幅
0  中信证券  24.78  0.05
1  国泰君安  20.15 -0.02
2  海通证券  14.03  0.03

创建DataFrame:从元组列表

Listing 6: 从元组列表创建DataFrame
展开从元组列表创建DataFrame代码
# 元组列表,每个元组代表一行数据
data_tuples = [
    ('600519.SH', '贵州茅台', 1850.00),
    ('000858.SZ', '五粮液', 220.50),
    ('600036.SH', '招商银行', 45.20)
]
# 创建DataFrame并指定列名
df2 = pd.DataFrame(data_tuples, columns=['代码', '名称', '价格'])
print(df2)
          代码    名称      价格
0  600519.SH  贵州茅台  1850.0
1  000858.SZ   五粮液   220.5
2  600036.SH  招商银行    45.2

创建DataFrame:从字典列表

Listing 7: 从字典列表创建DataFrame
展开从字典列表创建DataFrame代码
# 字典列表,每个字典代表一行数据
data_dict_list = [
    {'code': '600519.SH', 'name': '贵州茅台', 'price': 1850.00},
    {'code': '000858.SZ', 'name': '五粮液', 'price': 220.50},
    {'code': '600036.SH', 'name': '招商银行', 'price': 45.20}
]
# 字典的键自动成为列名
df3 = pd.DataFrame(data_dict_list)
print(df3)
        code  name   price
0  600519.SH  贵州茅台  1850.0
1  000858.SZ   五粮液   220.5
2  600036.SH  招商银行    45.2

创建DataFrame:从NumPy数组

Listing 8: 从NumPy数组创建DataFrame
展开从NumPy数组创建DataFrame代码
# 生成5行3列的标准正态分布随机数
arr = np.random.randn(5, 3)

# 从NumPy数组创建DataFrame
df4 = pd.DataFrame(
    arr,
    index=['row1', 'row2', 'row3', 'row4', 'row5'],
    columns=['A', 'B', 'C']
)
print(df4)
             A         B         C
row1  0.572031  0.164163  0.864984
row2  0.056765  0.773268  0.000643
row3 -1.161109 -0.817363  1.480771
row4 -0.292531  1.436584 -0.740262
row5  0.811554  0.342512  0.794984

访问DataFrame的列

Listing 9: 访问DataFrame的列数据
展开访问DataFrame列的三种方法代码
data = {
    '中国卫星': [-0.0351, 0.0172, -0.0035, -0.0246, 0.0394],
    '中国软件': [-0.0139, 0.0243, -0.0338, 0.0146, 0.0001],
    '中国银行': [-0.0139, 0.0243, -0.0338, 0.0146, 0.0001],
    '上汽集团': [0.0212, 0.0021, -0.0298, -0.0027, -0.0143]
}
index = ['20200525', '20200526', '20200527', '20200528', '20200529']
df = pd.DataFrame(data, index=index)

# 方法1:点号访问(列名无空格时可用)
print('点号访问:')
print(df.中国卫星.head(3))

# 方法2:方括号访问(通用方法,推荐)
print('\n方括号访问:')
print(df['中国软件'].head(3))

# 方法3:同时访问多列
print('\n多列访问:')
print(df[['中国卫星', '中国软件']].head(3))
点号访问:
20200525   -0.0351
20200526    0.0172
20200527   -0.0035
Name: 中国卫星, dtype: float64

方括号访问:
20200525   -0.0139
20200526    0.0243
20200527   -0.0338
Name: 中国软件, dtype: float64

多列访问:
            中国卫星    中国软件
20200525 -0.0351 -0.0139
20200526  0.0172  0.0243
20200527 -0.0035 -0.0338

访问DataFrame的行

Listing 10: 使用loc和iloc访问行数据
展开loc与iloc访问行代码
# loc:按标签访问
print('loc访问单行:')
print(df.loc['20200526'])

print('\nloc访问多行:')
print(df.loc[['20200526', '20200527']])

# iloc:按位置访问
print('\niloc访问第1行:')
print(df.iloc[0])

print('\niloc访问前2行:')
print(df.iloc[0:2])
loc访问单行:
中国卫星    0.0172
中国软件    0.0243
中国银行    0.0243
上汽集团    0.0021
Name: 20200526, dtype: float64

loc访问多行:
            中国卫星    中国软件    中国银行    上汽集团
20200526  0.0172  0.0243  0.0243  0.0021
20200527 -0.0035 -0.0338 -0.0338 -0.0298

iloc访问第1行:
中国卫星   -0.0351
中国软件   -0.0139
中国银行   -0.0139
上汽集团    0.0212
Name: 20200525, dtype: float64

iloc访问前2行:
            中国卫星    中国软件    中国银行    上汽集团
20200525 -0.0351 -0.0139 -0.0139  0.0212
20200526  0.0172  0.0243  0.0243  0.0021

访问单个值

Listing 11: 访问DataFrame中的单个值
展开访问单个值代码
# 使用loc(标签定位)
value_loc = df.loc['20200526', '中国卫星']
print(f'loc访问: df.loc["20200526", "中国卫星"] = {value_loc:.4f}')

# 使用iloc(位置定位)
value_iloc = df.iloc[0, 0]
print(f'iloc访问: df.iloc[0, 0] = {value_iloc:.4f}')
loc访问: df.loc["20200526", "中国卫星"] = 0.0172
iloc访问: df.iloc[0, 0] = -0.0351

查看DataFrame基本信息

Listing 12: 查看DataFrame的结构信息
展开DataFrame基本信息查看代码
# 形状(行, 列)
print(f'形状: {df.shape}')

# 数据类型
print(f'\n数据类型:')
print(df.dtypes)

# 前3行数据
print(f'\n前3行:')
print(df.head(3))
形状: (5, 4)

数据类型:
中国卫星    float64
中国软件    float64
中国银行    float64
上汽集团    float64
dtype: object

前3行:
            中国卫星    中国软件    中国银行    上汽集团
20200525 -0.0351 -0.0139 -0.0139  0.0212
20200526  0.0172  0.0243  0.0243  0.0021
20200527 -0.0035 -0.0338 -0.0338 -0.0298

Series运算:自动索引对齐

Listing 13: Series运算的索引对齐机制
展开Series索引自动对齐代码
s1 = pd.Series([10, 20, 30], index=['a', 'b', 'c'])  # 创建第一条带标签序列
s2 = pd.Series([5, 15, 25], index=['a', 'b', 'd'])  # 创建第二条错位标签序列
print('Series 1:', s1.values, '索引:', list(s1.index))  # 输出第一条序列结构
print('Series 2:', s2.values, '索引:', list(s2.index))  # 输出第二条序列结构
aligned_sum = s1 + s2  # 按标签自动对齐并相加
print('\n加法(自动对齐):')  # 输出结果标题
print(aligned_sum)  # 显示错位标签产生的缺失
Series 1: [10 20 30] 索引: ['a', 'b', 'c']
Series 2: [ 5 15 25] 索引: ['a', 'b', 'd']

加法(自动对齐):
a    15.0
b    35.0
c     NaN
d     NaN
dtype: float64

核心机制:只有相同索引的值才会运算,不同的产生 NaN;本章只诊断错位,不用填充值替代未知观测。

扩展预览边界|以下内容不纳入本章随堂练习

以下页面为第 11、13、16 章的路线图。课堂主路径可直接跳到“本章小结”;需要预习时再展开对应代码。

扩展预览|DataFrame统计摘要(第13章)

Listing 14: DataFrame的描述性统计
展开统计摘要describe代码
# describe():一键查看统计摘要
print(df.describe())
# 包含: count(数量)、mean(均值)、std(标准差)
# min(最小值)、25%/50%/75%(分位数)、max(最大值)
           中国卫星      中国软件      中国银行      上汽集团
count  5.000000  5.000000  5.000000  5.000000
mean  -0.001320 -0.001740 -0.001740 -0.004700
std    0.030368  0.023044  0.023044  0.018995
min   -0.035100 -0.033800 -0.033800 -0.029800
25%   -0.024600 -0.013900 -0.013900 -0.014300
50%   -0.003500  0.000100  0.000100 -0.002700
75%    0.017200  0.014600  0.014600  0.002100
max    0.039400  0.024300  0.024300  0.021200

扩展预览|DataFrame转置(第11章)

Listing 15: DataFrame的转置操作
展开DataFrame转置代码
# 转置:行列互换
print('转置前形状:', df.shape)
print('\n转置后:')
print(df.T)
print('\n转置后形状:', df.T.shape)
转置前形状: (5, 4)

转置后:
      20200525  20200526  20200527  20200528  20200529
中国卫星   -0.0351    0.0172   -0.0035   -0.0246    0.0394
中国软件   -0.0139    0.0243   -0.0338    0.0146    0.0001
中国银行   -0.0139    0.0243   -0.0338    0.0146    0.0001
上汽集团    0.0212    0.0021   -0.0298   -0.0027   -0.0143

转置后形状: (4, 5)

扩展预览|条件筛选:单条件(第11章)

Listing 16: DataFrame的单条件筛选
展开单条件筛选代码
# 筛选中国卫星涨幅为正的交易日
print('中国卫星涨幅>0的交易日:')
positive = df[df.中国卫星 > 0]
print(positive)
中国卫星涨幅>0的交易日:
            中国卫星    中国软件    中国银行    上汽集团
20200526  0.0172  0.0243  0.0243  0.0021
20200529  0.0394  0.0001  0.0001 -0.0143

扩展预览|条件筛选:多条件与 query(第11章)

Listing 17: DataFrame的多条件筛选与query方法
展开多条件筛选与query代码
# 多条件:使用 & (且) 连接
print('中国卫星>0 且 中国软件>0:')
multi_cond = df[(df.中国卫星 > 0) & (df.中国软件 > 0)]
print(multi_cond)

# query方法:语法更直观
print('\nquery方法筛选:')
query_result = df.query('中国卫星 > 0 and 中国软件 > 0')
print(query_result)
中国卫星>0 且 中国软件>0:
            中国卫星    中国软件    中国银行    上汽集团
20200526  0.0172  0.0243  0.0243  0.0021
20200529  0.0394  0.0001  0.0001 -0.0143

query方法筛选:
            中国卫星    中国软件    中国银行    上汽集团
20200526  0.0172  0.0243  0.0243  0.0021
20200529  0.0394  0.0001  0.0001 -0.0143

扩展预览|DataFrame算术运算(第11章)

Listing 18: DataFrame的算术运算
展开DataFrame算术运算代码
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [10, 20, 30], 'B': [40, 50, 60]})

# DataFrame加法
print('DataFrame加法:')
print(df1 + df2)

# 标量运算(广播机制)
print('\nDataFrame乘以标量10:')
print(df1 * 10)
DataFrame加法:
    A   B
0  11  44
1  22  55
2  33  66

DataFrame乘以标量10:
    A   B
0  10  40
1  20  50
2  30  60

扩展预览|统计函数:按列计算(第13章)

Listing 19: 按列计算统计指标
展开按列统计计算代码
data = {
    '中国卫星': [-0.0351, 0.0172, -0.0035, -0.0246, 0.0394],
    '中国软件': [-0.0139, 0.0243, -0.0338, 0.0146, 0.0001],
    '中国银行': [-0.0139, 0.0243, -0.0338, 0.0146, 0.0001],
    '上汽集团': [0.0212, 0.0021, -0.0298, -0.0027, -0.0143]
}
index = ['20200525', '20200526', '20200527', '20200528', '20200529']
df = pd.DataFrame(data, index=index)

# 每只股票的平均涨跌幅
print('均值(axis=0, 按列):')
print(df.mean())

# 每只股票的波动率
print('\n标准差:')
print(df.std())
均值(axis=0, 按列):
中国卫星   -0.00132
中国软件   -0.00174
中国银行   -0.00174
上汽集团   -0.00470
dtype: float64

标准差:
中国卫星    0.030368
中国软件    0.023044
中国银行    0.023044
上汽集团    0.018995
dtype: float64

扩展预览|统计函数:按行计算(第13章)

Listing 20: 按行计算统计指标
展开按行统计计算代码
# 每个交易日所有股票的平均涨跌幅
print('均值(axis=1, 按行):')
print(df.mean(axis=1))
均值(axis=1, 按行):
20200525   -0.010425
20200526    0.016975
20200527   -0.025225
20200528    0.000475
20200529    0.006325
dtype: float64
  • axis=0(默认):沿列方向计算 → 每只股票的统计值
  • axis=1:沿行方向计算 → 每个交易日的统计值

扩展预览|累积收益率计算(第53章)

Listing 21: 使用Pandas计算累积收益率
展开累积收益率计算代码
# 计算累积收益率
cum_returns = (1 + df).cumprod() - 1  # 逐日累乘收益因子后再减1,得到区间累积收益率
print('累积收益率(展示最后3个交易日,体现区间终值):')  # 只打印尾部3行以控制幻灯片高度
print(cum_returns.tail(3).round(4))  # 四位小数展示最终累积结果
累积收益率(展示最后3个交易日,体现区间终值):
            中国卫星    中国软件    中国银行    上汽集团
20200527 -0.0219 -0.0241 -0.0241 -0.0072
20200528 -0.0460 -0.0098 -0.0098 -0.0098
20200529 -0.0084 -0.0097 -0.0097 -0.0240

计算步骤

  1. 1 + df:涨跌幅 → 收益率因子(如 -0.01 → 0.99)
  2. .cumprod():计算累积乘积
  3. - 1:因子 → 累积收益率

扩展预览|缺失值检测(第16章)

Listing 22: 缺失值的创建与检测
展开缺失值检测代码
# 创建包含缺失值的DataFrame
df_nan = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': [9, 10, 11, 12]
})

print('原始数据:')
print(df_nan)

# 检测缺失值
print('\n缺失值位置(True=缺失):')
print(df_nan.isnull())
原始数据:
     A    B   C
0  1.0  5.0   9
1  2.0  NaN  10
2  NaN  NaN  11
3  4.0  8.0  12

缺失值位置(True=缺失):
       A      B      C
0  False  False  False
1  False   True  False
2   True   True  False
3  False  False  False

扩展预览|缺失值删除(第16章)

Listing 23: 删除缺失值的方法
展开缺失值删除代码
df_nan = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': [9, 10, 11, 12]
})

# 删除包含缺失值的行
print('删除含缺失值的行:')
print(df_nan.dropna())

# 删除包含缺失值的列
print('\n删除含缺失值的列:')
print(df_nan.dropna(axis=1))
删除含缺失值的行:
     A    B   C
0  1.0  5.0   9
3  4.0  8.0  12

删除含缺失值的列:
    C
0   9
1  10
2  11
3  12

扩展预览|缺失值填充(第16章)

Listing 24: 填充缺失值的常用方法
展开缺失值填充代码
df_nan = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': [9, 10, 11, 12]
})

# 方法1:用0填充
print('用0填充:')
print(df_nan.fillna(0))

# 方法2:前向填充(用前一个有效值填充)
print('\n前向填充:')
print(df_nan.ffill())

# 方法3:用均值填充
print('\n用均值填充:')
print(df_nan.fillna(df_nan.mean()))
用0填充:
     A    B   C
0  1.0  5.0   9
1  2.0  0.0  10
2  0.0  0.0  11
3  4.0  8.0  12

前向填充:
     A    B   C
0  1.0  5.0   9
1  2.0  5.0  10
2  2.0  5.0  11
3  4.0  8.0  12

用均值填充:
          A    B   C
0  1.000000  5.0   9
1  2.000000  6.5  10
2  2.333333  6.5  11
3  4.000000  8.0  12

本章小结

概念 说明 关键方法
Series 一维带标签数组 pd.Series()
DataFrame 二维表格数据 pd.DataFrame()
索引访问 标签/位置 loc / iloc
标签对齐 同名索引自动配对 Series + Series
扩展预览 筛选、统计、缺失值 第11、13、16章

随堂练习

  • 问题 1|需要准备哪些数据?:带索引的 Series、二维数组和字段字典。
  • 问题 2|需要完成哪些操作?:运行 lst-df-from-numpylst-series-align,创建 DataFrame 并观察标签对齐。
  • 问题 3|应得到哪些结果?:行列标签、shape 与标签对齐后缺失位置。
  • 问题 4|怎样确认结果可靠?:检查索引唯一、列数与数组宽度一致;重复索引或意外 NaN 时先检查原因。
  • 问题 5|换一个情境,怎样继续应用?:把创建步骤应用到长三角公司季度表。
  • 作答提示:请依次写清所用数据、分析过程、所得结果、核对方法和拓展思考。课程所需数据见前言中的下载入口;教学平台固定题按页面说明完成。

教师参考解答|答案与说明 1

  • 补充练习|从 NumPy 数组建表

教师参考解答|代码 1

展开代码(代码区可独立滚动)
import numpy as np  # 导入数组计算库
import pandas as pd  # 导入表格处理库
return_array=np.array([[0.01,0.02],[-0.02,0.03]])  # 准备无缺失二维收益数组
return_frame=pd.DataFrame(return_array,index=pd.to_datetime(['2026-01-05','2026-01-06']),columns=['A','B'])  # 绑定日期与证券标签
left=pd.Series([1,2],index=['A','B'])  # 创建左侧标签序列
right=pd.Series([10,20],index=['B','C'])  # 创建错位标签序列
aligned=left+right  # 观察标签自动对齐结果
assert return_frame.shape==(2,2)  # 核对数组宽度与列标签数量一致
assert return_frame.index.is_unique  # 核对日期索引唯一
print(return_frame.shape,list(return_frame.columns),aligned.to_dict())  # 输出核心创建与对齐依据

教师参考解答|答案与说明 2

  • 解释与拓展应用答案:Pandas 增加业务标签和自动对齐,键错位会产生新缺失;拓展应用到长三角季度表时先核对索引唯一与字段宽度,缺失处理留到第16章。

  • 所用数据与字段:Series=股票索引;DataFrame=交易日×股票

  • 参考代码或推导(平台保护块之外):

教师参考解答|代码 2

展开代码(代码区可独立滚动)
import pandas as pd  # 导入表格库
s=pd.Series([0.01,-0.02],index=['A','B'],name='return')  # 创建序列
df=pd.DataFrame({'A':[0.01,0.02],'B':[-0.02,0.01]},index=pd.to_datetime(['2026-01-01','2026-01-02']))  # 创建数据框
print(s.shape,df.shape,df.index.dtype)  # 核对结构

教师参考解答|答案与说明 3

  • 参考结果:(2,)、(2,2)、日期索引
  • 边界 / 局限:自动对齐按标签发生
  • 常见错误:长度不一致;日期仍是字符串